package com.aphrodite.util;

/**
 * Provide an iterator over a string
 * 
 * @author kentelt
 * 
 */
public final class StringCharacterIterator implements CharacterIterator {

	private int begin;

	private int end;

	private int pos;

	private String text;

	public StringCharacterIterator(String s) {
		this(s, 0);
	}

	public StringCharacterIterator(String s, int i) {
		this(s, 0, s.length(), i);
	}

	public StringCharacterIterator(char[] charArray, int offset, int length) {
		this(new String(charArray), offset, length, 0);
	}

	public StringCharacterIterator(String s, int offset, int length, int startIndex) {
		if (s == null)
			throw new NullPointerException();
		text = s;
		if (offset < 0 || offset > length || length > s.length())
			throw new IllegalArgumentException("Invalid substring range");
		if (startIndex < offset || startIndex > length) {
			throw new IllegalArgumentException("Invalid position");
		} else {
			begin = offset;
			end = length;
			pos = startIndex;
			return;
		}
	}

	public char current() {
		if (pos >= begin && pos < end)
			return text.charAt(pos);
		else
			return '\uFFFF';
	}

	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!(obj instanceof StringCharacterIterator))
			return false;
		StringCharacterIterator stringcharacteriterator = (StringCharacterIterator) obj;
		if (hashCode() != stringcharacteriterator.hashCode())
			return false;
		if (!text.equals(stringcharacteriterator.text))
			return false;
		return pos == stringcharacteriterator.pos && begin == stringcharacteriterator.begin
				&& end == stringcharacteriterator.end;
	}

	public char first() {
		pos = begin;
		return current();
	}

	public int getBeginIndex() {
		return begin;
	}

	public int getEndIndex() {
		return end;
	}

	public int getIndex() {
		return pos;
	}

	public int hashCode() {
		return text.hashCode() ^ pos ^ begin ^ end;
	}

	public boolean hasMoreChars() {
		return pos <= end;
	}

	public char last() {
		if (end != begin)
			pos = end - 1;
		else
			pos = end;
		return current();
	}

	public char next() {
		if (pos < end - 1) {
			pos++;
			return text.charAt(pos);
		} else {
			pos = end;
			return '\uFFFF';
		}
	}

	public char previous() {
		if (pos > begin) {
			pos--;
			return text.charAt(pos);
		} else {
			return '\uFFFF';
		}
	}

	public char setIndex(int i) {
		if (i < begin || i > end) {
			throw new IllegalArgumentException("Invalid index");
		} else {
			pos = i;
			return current();
		}
	}

	public void setText(String s) {
		if (s == null) {
			throw new NullPointerException();
		} else {
			text = s;
			begin = 0;
			end = s.length();
			pos = 0;
			return;
		}
	}

	public char charAt(int index) {
		return text.charAt(index);
	}

	public String substring(int offset, int length) {
		return text.substring(offset, length);
	}

	public String substring(int offset) {
		return substring(offset, text.length());
	}

	public boolean isEnd(int pos) {
		return (pos >= text.length());
	}

}